﻿using CommonBase;
using EnvCommonUtility;
using EnvControlLib;
using Microsoft.Practices.Prism.Events;
using SurveillanceLib;
using SurveillancePro.Base.Common;
using SurveillancePro.Base.Events;
using SurveillancePro.Base.ViewModels;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;

namespace ToolkitMgtModule.ViewModels
{
    /// <summary>
    /// 文件回放
    /// </summary>
    public class ViewModel_PlayVideo : WorkspaceViewModel
    {
        #region Const Fields

        private const int SPLITSCREEN_COUNT = 4; // 默认分屏数
        private const double SLIDER_MAXVALUE = 100.0; // 进度条最大刻度
        private const uint LARGECHANGE_DEFAULTVALUE = 5; // 快进、快退步长

        #endregion

        #region Private Fields

        // 默认 SPLITSCREEN_COUNT 个回放视频窗口[0~SPLITSCREEN_COUNT-1] + 1个最大化窗口[SPLITSCREEN_COUNT]
        private FilePlayBackModel[] _pFilePlayBack; // 文件回放
        private List<EnvVideoPanel> _panelCurrentList = null; // 记录最新的分屏列表
        private int _panelIndex; // 记录所选回放视频窗口序号，仅用于进度回调函数中

        #endregion

        #region Constructor

        public ViewModel_PlayVideo(IEventAggregator eventAggregator)
        {
            base.ViewName = SurveillancePro.Base.Common.ViewNames.ToolkitMgtModule_DownloadFile;
            base.HeaderTitle = "录像回放";
            base.HeaderImageSource = string.Format(ConstantString.IMAGE_URL, "Question");
            base.IsShowCloseButton = Visibility.Collapsed;

            #region 模块间通信
            // 接收主模块的消息(EnvPanelOperationExt)
            OpenModelEvent openEvent = eventAggregator.GetEvent<OpenModelEvent>();
            openEvent.Subscribe(_manageData, ThreadOption.UIThread, true,
                x => x.ModelName == this.GetType().Name);
            #endregion

            _pFilePlayBack = new FilePlayBackModel[SPLITSCREEN_COUNT + 1];
            for (int i = 0; i < _pFilePlayBack.Length; i++)
            {
                _pFilePlayBack[i] = new FilePlayBackModel();
            }
        }

        #endregion

        #region Public Property

        /// <summary>
        /// 获取文件回放列表
        /// </summary>
        public FilePlayBackModel[] FilePlayBackList
        {
            get
            {
                return this._pFilePlayBack;
            }
        }

        private bool _isPlay;
        /// <summary>
        /// 是否回放
        /// </summary>
        public bool IsPlay
        {
            get { return _isPlay; }
            set
            {
                if (_isPlay == value) return;
                _isPlay = value;
                base.OnPropertyChanged("IsPlay");
            }
        }

        private double _sliderValue;
        /// <summary>
        /// 进度条当前值
        /// </summary>
        public double SliderValue
        {
            get { return _sliderValue; }
            set
            {
                if (_sliderValue == value) return;
                _sliderValue = value;
                base.OnPropertyChanged("SliderValue");
            }
        }

        #endregion

        #region Base Class Overrides

        protected override void OnDispose()
        {
            _dispose();
        }

        #endregion

        #region Public Events

        /// <summary>
        /// 视频回放面板加载时
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void VideoPanel_Loaded(object sender, RoutedEventArgs e)
        {
            try
            {
                #region Tab 切换时，也会执行 Loaded
                if (_pFilePlayBack != null)
                {
                    for (int i = 0; i < _pFilePlayBack.Length; i++)
                    {
                        if (_panelCurrentList != null &&
                            i < _panelCurrentList.Count &&
                            _panelCurrentList[i] != null &&
                            _pFilePlayBack[i].SelectedFile != null &&
                            _pFilePlayBack[i].SelectedFile.SelectedDriver != null &&
                            _pFilePlayBack[i].SelectedFile.SelectedDriver.Driver_Instance != null &&
                            !string.IsNullOrWhiteSpace(_pFilePlayBack[i].PlayBackHandle))
                        {
                            if (!_stopVideo(_pFilePlayBack[i].SelectedFile, i, false)) // 1. 先逐个停止视频回放
                            {
#if DEBUG
                                Debug.WriteLine("停止回放失败！");
#endif
                            }
                            else
                            {
#if DEBUG
                                Debug.WriteLine("停止回放成功！");
#endif
                            }
                        }
                    }
                }
                #endregion

                #region 默认分屏操作
                Panel splitScreen = sender as Panel;
                EnvPanelOperationExt _panelOperation = new EnvPanelOperationExt();

                EnvVideoPanel panel = new EnvVideoPanel() // 设置最大化视频窗口
                {
                    Height = splitScreen.ActualHeight,
                    Width = splitScreen.ActualWidth,
                    Visibility = Visibility.Collapsed, // 隐藏最大化视频窗口
                    Tag = new TagModel()
                    {
                        Panel_Index = SPLITSCREEN_COUNT, // 下标最大值为最大化视频窗口序号
                    },
                };

                if (panel.DataContext != null &&
                    panel.DataContext is ViewModel_EnvVideoPanel)
                {
                    ViewModel_EnvVideoPanel vm_EnvVideoPanel = panel.DataContext as ViewModel_EnvVideoPanel;
                    vm_EnvVideoPanel.IsMaxPanel = true;
                    vm_EnvVideoPanel.IsRealPlayPanel = Visibility.Collapsed;
                    vm_EnvVideoPanel.PanelCurrentList = _panelCurrentList;
                    vm_EnvVideoPanel.SplitScreen = splitScreen;
                    vm_EnvVideoPanel.MaxScreen = panel;
                    vm_EnvVideoPanel.DoubleAction = null;
                    vm_EnvVideoPanel.ChangeBorderColorAction = EnvUtilities.ChangeBorderColor4Preview;
                    vm_EnvVideoPanel.ShowMaxScreenAction = _showMaxScreen;
                    vm_EnvVideoPanel.HideMaxScreenAction = _hideMaxScreen;
                    vm_EnvVideoPanel.StopPanelRealPlayAction = _stopPanelPlayBack;
                }

                _panelCurrentList = _panelOperation.SplitScreen(SPLITSCREEN_COUNT,
                    splitScreen, panel, null, _showMaxScreen, _hideMaxScreen, _stopPanelPlayBack); // SPLITSCREEN_COUNT 画面分割

                splitScreen.Children.Add(panel); // 将最大化视频窗口添加到容器中
                _panelCurrentList.Add(panel); // 将最大化视频窗口添加到列表中
                #endregion

                #region Tab 切换时，也会执行 Loaded
                if (_pFilePlayBack != null)
                {
                    for (int i = 0; i < _pFilePlayBack.Length; i++)
                    {
                        if (_panelCurrentList != null &&
                            i < _panelCurrentList.Count &&
                            _panelCurrentList[i] != null &&
                            _pFilePlayBack[i].SelectedFile != null &&
                            _pFilePlayBack[i].SelectedFile.SelectedDriver != null &&
                            _pFilePlayBack[i].SelectedFile.SelectedDriver.Driver_Instance != null &&
                            !string.IsNullOrWhiteSpace(_pFilePlayBack[i].SelectedFile.SelectedDriver.Driver_LoginID))
                        {
                            if (_playVideo(_pFilePlayBack[i].SelectedFile, i,
                                _panelCurrentList[i]))  // 2. 再逐个回放视频
                            {
#if DEBUG
                                Debug.WriteLine("回放成功！");
#endif
                            }
                            else
                            {
#if DEBUG
                                Debug.WriteLine("回放失败！");
#endif
                            }
                        }
                    }
                }
                #endregion

                #region 默认高亮选中第一个回放视频窗口
                if (_panelCurrentList != null && _panelCurrentList.Count > 0)
                {
                    EnvUtilities.ChangeBorderColor4Preview(_panelCurrentList[0],
                        _panelCurrentList);// 默认选中第一个回放视频窗口
                }
                #endregion
            }
            catch (System.Exception ex)
            {
#if DEBUG
                Debug.WriteLine(ex.Message);
#endif
            }
        }

        /// <summary>
        /// 打开文件
        /// </summary>
        /// <param name="sender"></param>
        public void PlayerController_FileEvent(object sender, RoutedEventArgs e)
        {
            try
            {
                MessageBox.Show("开发中...");
            }
            catch (System.Exception ex)
            {
#if DEBUG
                Debug.WriteLine(ex.Message);
#endif
            }
        }

        /// <summary>
        /// 快放
        /// </summary>
        /// <param name="sender"></param>
        public void PlayerController_FastEvent(object sender, RoutedEventArgs e)
        {
            try
            {
                if (_pFilePlayBack != null &&
                    EnvPanelOperationExt.SelectedPanel != null &&
                    EnvPanelOperationExt.SelectedPanel.Tag != null &&
                    EnvPanelOperationExt.SelectedPanel.Tag is TagModel &&
                    (EnvPanelOperationExt.SelectedPanel.Tag as TagModel).Driver_Instance != null)
                {
                    TagModel panelTag = EnvPanelOperationExt.SelectedPanel.Tag as TagModel;
                    if (!_pFilePlayBack[panelTag.Panel_Index].IsPlay) // 未回放时
                    {
                        PlayerController_PlayEvent(sender, e);
                    }

                    if (panelTag.Driver_Instance.PlayBackControl(_pFilePlayBack[panelTag.Panel_Index].PlayBackHandle,
                        "Fast")) // 快放控制
                    {
#if DEBUG
                        Debug.WriteLine("快放控制成功。");
#endif
                        ViewModel_EnvVideoPanel vm_EnvVideoPanel = EnvPanelOperationExt.SelectedPanel.DataContext as ViewModel_EnvVideoPanel;
                        // 设置视频窗口文本标题信息
                        if (vm_EnvVideoPanel != null &&
                            panelTag.Parameter == null) // Parameter 存放回放速度，未快放
                        {
                            panelTag.Parameter = 1;
                            vm_EnvVideoPanel.VideoInformation =
                                string.Format("[X{0}]{1}", Math.Pow(2, (int)panelTag.Parameter),
                                vm_EnvVideoPanel.VideoInformation);
                        }
                        else if (vm_EnvVideoPanel != null &&
                            panelTag.Parameter != null) // 已快放
                        {
                            panelTag.Parameter = ((int)panelTag.Parameter) + 1; // 速度++
                            _showPlaySpeedVideoInformation(panelTag, vm_EnvVideoPanel); // 显示回放速度标题
                        }
                    }
                    else
                    {
#if DEBUG
                        Debug.WriteLine("快放控制失败。");
#endif
                        AutoCloseNoticeWindow.Show("已达最大值！", false);
                    }
                }
            }
            catch (System.Exception ex)
            {
#if DEBUG
                Debug.WriteLine(ex.Message);
#endif
            }
        }

        /// <summary>
        /// 回放 | 暂停
        /// </summary>
        /// <param name="sender"></param>
        public void PlayerController_PlayEvent(object sender, RoutedEventArgs e)
        {
            try
            {
                if (_pFilePlayBack != null &&
                    EnvPanelOperationExt.SelectedPanel != null &&
                    EnvPanelOperationExt.SelectedPanel.Tag != null &&
                    EnvPanelOperationExt.SelectedPanel.Tag is TagModel &&
                    (EnvPanelOperationExt.SelectedPanel.Tag as TagModel).Driver_Instance != null)
                {
                    TagModel panelTag = EnvPanelOperationExt.SelectedPanel.Tag as TagModel;
                    if (_pFilePlayBack[panelTag.Panel_Index].IsPlay) // 回放中
                    {
                        if (panelTag.Driver_Instance.PlayBackControl(_pFilePlayBack[panelTag.Panel_Index].PlayBackHandle,
                            "Pause")) // 暂停回放
                        {
#if DEBUG
                            Debug.WriteLine("暂停回放成功。");
#endif
                            IsPlay = _pFilePlayBack[panelTag.Panel_Index].IsPlay = !_pFilePlayBack[panelTag.Panel_Index].IsPlay;
                        }
                        else
                        {
#if DEBUG
                            Debug.WriteLine("暂停回放失败。");
#endif
                            AutoCloseNoticeWindow.Show("暂停回放失败。", false);
                        }
                    }
                    else
                    {
                        if (panelTag.Driver_Instance.PlayBackControl(_pFilePlayBack[panelTag.Panel_Index].PlayBackHandle,
                            "Play")) // 回放
                        {
#if DEBUG
                            Debug.WriteLine("回放成功。");
#endif
                            IsPlay = _pFilePlayBack[panelTag.Panel_Index].IsPlay = !_pFilePlayBack[panelTag.Panel_Index].IsPlay;
                        }
                        else
                        {
#if DEBUG
                            Debug.WriteLine("回放失败。");
#endif
                            AutoCloseNoticeWindow.Show("回放失败。", false);
                        }
                    }
                }
            }
            catch (System.Exception ex)
            {
#if DEBUG
                Debug.WriteLine(ex.Message);
#endif
            }
        }

        /// <summary>
        /// 慢放
        /// </summary>
        /// <param name="sender"></param>
        public void PlayerController_SlowEvent(object sender, RoutedEventArgs e)
        {
            try
            {
                if (_pFilePlayBack != null &&
                    EnvPanelOperationExt.SelectedPanel != null &&
                    EnvPanelOperationExt.SelectedPanel.Tag != null &&
                    EnvPanelOperationExt.SelectedPanel.Tag is TagModel &&
                    (EnvPanelOperationExt.SelectedPanel.Tag as TagModel).Driver_Instance != null)
                {
                    TagModel panelTag = EnvPanelOperationExt.SelectedPanel.Tag as TagModel;
                    if (!_pFilePlayBack[panelTag.Panel_Index].IsPlay) // 未回放时
                    {
                        PlayerController_PlayEvent(sender, e);
                    }

                    if (panelTag.Driver_Instance.PlayBackControl(_pFilePlayBack[panelTag.Panel_Index].PlayBackHandle,
                        "Slow")) // 慢放控制
                    {
#if DEBUG
                        Debug.WriteLine("慢放控制成功。");
#endif
                        ViewModel_EnvVideoPanel vm_EnvVideoPanel = EnvPanelOperationExt.SelectedPanel.DataContext as ViewModel_EnvVideoPanel;
                        // 设置视频窗口文本标题信息
                        if (vm_EnvVideoPanel != null &&
                            panelTag.Parameter == null) // Parameter 存放回放速度，未慢放
                        {
                            panelTag.Parameter = -1;
                            vm_EnvVideoPanel.VideoInformation =
                                string.Format("[X1/{0}]{1}", (int)(1 / Math.Pow(2, (int)panelTag.Parameter)),
                                vm_EnvVideoPanel.VideoInformation);
                        }
                        else if (vm_EnvVideoPanel != null &&
                            panelTag.Parameter != null) // 已慢放
                        {
                            panelTag.Parameter = ((int)panelTag.Parameter) - 1; // 速度--
                            _showPlaySpeedVideoInformation(panelTag, vm_EnvVideoPanel); // 显示回放速度标题
                        }
                    }
                    else
                    {
#if DEBUG
                        Debug.WriteLine("慢放控制失败。");
#endif
                        AutoCloseNoticeWindow.Show("已达最小值！", false);
                    }
                }
            }
            catch (System.Exception ex)
            {
#if DEBUG
                Debug.WriteLine(ex.Message);
#endif
            }
        }

        /// <summary>
        /// 停止
        /// </summary>
        /// <param name="sender"></param>
        public void PlayerController_StopEvent(object sender, RoutedEventArgs e)
        {
            try
            {
                EnvVideoPanel selectedPanel = sender as EnvVideoPanel;
                if (_pFilePlayBack != null && selectedPanel != null &&
                    selectedPanel.Tag != null && selectedPanel.Tag is TagModel &&
                    (selectedPanel.Tag as TagModel).Driver_Instance != null)
                {
                    TagModel panelTag = selectedPanel.Tag as TagModel;
                    if (!_stopVideo(_pFilePlayBack[panelTag.Panel_Index].SelectedFile, panelTag.Panel_Index, true)) // 停止回放视频
                    {
#if DEBUG
                        Debug.WriteLine("停止回放失败！");
#endif
                        AutoCloseNoticeWindow.Show("停止回放失败。", false);
                        return;
                    }
                    else
                    {
#if DEBUG
                        Debug.WriteLine("停止回放成功！");
#endif
                    }
                }
            }
            catch (System.Exception ex)
            {
#if DEBUG
                Debug.WriteLine(ex.Message);
#endif
            }
        }

        /// <summary>
        /// 进度条
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void PlayerController_ProgressSliderEvent(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            try
            {
                _playVideoInProgress(EnvPanelOperationExt.SelectedPanel, e.NewValue); // 进度回放
            }
            catch (System.Exception ex)
            {
#if DEBUG
                Debug.WriteLine(ex.Message);
#endif
            }
        }

        /// <summary>
        /// 快进
        /// </summary>
        /// <param name="sender"></param>
        public void PlayerController_ForwardEvent(object sender, RoutedEventArgs e)
        {
            try
            {
                if (SliderValue + LARGECHANGE_DEFAULTVALUE > SLIDER_MAXVALUE)
                    SliderValue = SLIDER_MAXVALUE;
                else
                    SliderValue += LARGECHANGE_DEFAULTVALUE;
            }
            catch (System.Exception ex)
            {
#if DEBUG
                Debug.WriteLine(ex.Message);
#endif
            }
        }

        /// <summary>
        /// 快退
        /// </summary>
        /// <param name="sender"></param>
        public void PlayerController_BackwardEvent(object sender, RoutedEventArgs e)
        {
            try
            {
                if (SliderValue - LARGECHANGE_DEFAULTVALUE < 0.0)
                    SliderValue = 0.0;
                else
                    SliderValue -= LARGECHANGE_DEFAULTVALUE;
            }
            catch (System.Exception ex)
            {
#if DEBUG
                Debug.WriteLine(ex.Message);
#endif
            }
        }

        #endregion

        #region Public Methods

        /// <summary>
        /// 回放所选文件
        /// </summary>
        /// <param name="selectedFile">所选文件</param>
        public void PlayVideo(FileDetailModel selectedFile)
        {
            try
            {
                if (selectedFile == null)
                    return;

                if (EnvPanelOperationExt.SelectedPanel != null &&
                    EnvPanelOperationExt.SelectedPanel.Tag != null &&
                    EnvPanelOperationExt.SelectedPanel.Tag is TagModel &&
                    selectedFile.SelectedDriver != null &&
                    selectedFile.SelectedDriver.Driver_Instance != null &&
                    !string.IsNullOrWhiteSpace(selectedFile.SelectedDriver.Driver_LoginID))
                {
                    TagModel panelTag = EnvPanelOperationExt.SelectedPanel.Tag as TagModel;
                    // 判断所选回放窗口是否正在回放视频
                    if (_panelCurrentList != null &&
                        panelTag.Panel_Index < _panelCurrentList.Count &&
                        _panelCurrentList[panelTag.Panel_Index] != null &&
                        _pFilePlayBack != null &&
                        panelTag.Panel_Index < _pFilePlayBack.Length &&
                        _pFilePlayBack[panelTag.Panel_Index] != null &&
                        !string.IsNullOrWhiteSpace(_pFilePlayBack[panelTag.Panel_Index].PlayBackHandle))
                    {
                        if (!_stopVideo(selectedFile, panelTag.Panel_Index, true)) // 停止回放视频
                        {
#if DEBUG
                            Debug.WriteLine("停止回放失败！");
#endif
                            return;
                        }
                        else
                        {
#if DEBUG
                            Debug.WriteLine("停止回放成功！");
#endif
                        }
                    }

                    // 判断是否存在同一设备的相同通道号
                    for (int i = 0; i < _pFilePlayBack.Length; i++)
                    {
                        if (_panelCurrentList != null &&
                            i < _panelCurrentList.Count &&
                            _panelCurrentList[i] != null &&
                            _pFilePlayBack[i].DriverIP == selectedFile.DriverIP &&
                            _pFilePlayBack[i].DriverChannel == selectedFile.DriverChannel)
                        {
                            if (!_stopVideo(selectedFile, i, true)) // 停止回放视频
                            {
#if DEBUG
                                Debug.WriteLine("停止回放失败！");
#endif
                                return;
                            }
                            else
                            {
#if DEBUG
                                Debug.WriteLine("停止回放成功！");
#endif
                                break;
                            }
                        }
                    }

                    if (_playVideo(selectedFile, panelTag.Panel_Index,
                        EnvPanelOperationExt.SelectedPanel)) // 视频回放
                    {
#if DEBUG
                        Debug.WriteLine("回放成功！");
#endif
                        //_focus2NextPanel(); // 将焦点自动循环移动到下一个视频窗口中
                    }
                    else
                    {
#if DEBUG
                        Debug.WriteLine("回放失败！");
#endif
                    }
                }
                else
                {
#if DEBUG
                    Debug.WriteLine("没有选择回放视频窗口!");
#endif
                    MessageBox.Show("没有选择回放视频窗口!", ConstantString.MSG_COMPANY);
                }
            }
            catch (System.Exception ex)
            {
#if DEBUG
                Debug.WriteLine(ex.Message);
#endif
            }
        }

        #endregion

        #region Private Methods

        #region 回调函数
        /// <summary>
        /// 进度回调函数
        /// <para>这里共用一个回调函数，注意分清各自窗口</para>
        /// </summary>
        /// <param name="lPlayHandle">回放句柄:CLIENT_PlayBackByRecordFile返回值</param>
        /// <param name="dwTotalSize">指本次回放总大小，单位为KB</param>
        /// <param name="dwDownLoadSize">指已经回放的大小，单位为KB，当其值为-1时表示本次回防结束</param>
        /// <param name="dwUser">用户数据</param>
        private void _fDownLoadPosCallBack(int lPlayHandle, uint dwTotalSize,
            uint dwDownLoadSize, IntPtr dwUser)
        {
            try
            {
                // 注：这里不能使用此语句，不要对界面进行频繁修改，否则会卡死！ Application.Current.Dispatcher.Invoke((Action)(() => { }));
                if (_pFilePlayBack != null && _panelIndex >= 0 && _panelIndex < _pFilePlayBack.Length &&
                    _pFilePlayBack[_panelIndex].PlayBackHandle == lPlayHandle.ToString()) // 限特定窗口
                {
                    if (dwDownLoadSize > dwTotalSize)
                    {
                        if (dwDownLoadSize == uint.MaxValue) // 表示回放完成
                        {
                            dwDownLoadSize = 0; // 重置进度条
                            IsPlay = _pFilePlayBack[_panelIndex].IsPlay = false; // 停止回放
                            // 注：这里不能停止回放，会卡死！
#if DEBUG
                            Debug.WriteLine("回放完成！");
#endif
                        }
                        else
                            dwDownLoadSize = dwTotalSize; // 防止显示超过 100%
                    }

                    SliderValue = SLIDER_MAXVALUE * dwDownLoadSize / dwTotalSize; // 计算进度值，双精度有点慢
                }
            }
            catch (System.Exception ex)
            {
#if DEBUG
                Debug.WriteLine(ex.Message);
#endif
            }
        }

        /// <summary>
        /// 实时监视数据回调【Static】
        /// </summary>
        /// <param name="lRealHandle">实时监视ID</param>
        /// <param name="dwDataType">标识回调出来的数据类型, 只有dwFlag设置标识的数据才会回调出来： 0:原始数据(与SaveRealData保存的数据一致); 1:标准视频数据;2:yuv数据 3:pcm音频数据</param>
        /// <param name="pBuffer">回调数据,根据数据类型的不同每次回调不同的长度的数据,除类型0, 其他数据类型都是按帧,每次回调一帧数据</param>
        /// <param name="dwBufSize">回调数据的长度, 根据不同的类型, 长度也不同, (单位字节)</param>
        /// <param name="dwUser">用户数据，就是上面输入的用户数据</param>
        private void _fDownLoadDataCallBack(int lRealHandle, uint dwDataType, IntPtr pBuffer,
            uint dwBufSize, uint dwUser)
        {
        }
        #endregion

        #region 主模块传入执行的方法
        /// <summary>
        /// 事件入口
        /// </summary>
        /// <param name="arg"></param>
        private void _manageData(OpenModelEventArg arg)
        {
            if (string.IsNullOrWhiteSpace(arg.FunctionName))
            {
#if DEBUG
                Debug.WriteLine("无效的执行操作，请输入方法名称！");
#endif
                return;
            }

            try
            {
                switch (arg.FunctionName)
                {
                    case "ChangePlayButtonState": // 修改播放器按钮状态
                        if (_pFilePlayBack != null &&
                            EnvPanelOperationExt.SelectedPanel != null &&
                            EnvPanelOperationExt.SelectedPanel.Tag != null &&
                            EnvPanelOperationExt.SelectedPanel.Tag is TagModel &&
                            (EnvPanelOperationExt.SelectedPanel.Tag as TagModel).Panel_Index >= 0 &&
                            (EnvPanelOperationExt.SelectedPanel.Tag as TagModel).Panel_Index < _pFilePlayBack.Length &&
                            _pFilePlayBack[(EnvPanelOperationExt.SelectedPanel.Tag as TagModel).Panel_Index] != null)
                        {
                            TagModel panelTag = EnvPanelOperationExt.SelectedPanel.Tag as TagModel;
                            _panelIndex = panelTag.Panel_Index; // 记录序号
                            IsPlay = _pFilePlayBack[_panelIndex].IsPlay; // 是否正在回放

                            if (panelTag.Driver_Instance == null)
                                SliderValue = 0.0; // 重置进度条
                        }
                        break;


                    default:
                        break;
                }
            }
            catch (System.Exception ex)
            {
#if DEBUG
                Debug.WriteLine(ex.Message);
#endif
                MessageBox.Show(ex.Message, ConstantString.MSG_COMPANY);
            }
        }
        #endregion

        /// <summary>
        /// 回放视频
        /// </summary>
        /// <param name="selectedFile">所选文件</param>
        /// <param name="panelIndex">窗口序号</param>
        /// <param name="selectedPanel">所选视频窗口</param>
        /// <returns>true: 回放成功；false: 回放失败</returns>
        private bool _playVideo(FileDetailModel selectedFile, int panelIndex,
            EnvVideoPanel selectedPanel)
        {
            if (_pFilePlayBack != null && panelIndex < _pFilePlayBack.Length &&
                _pFilePlayBack[panelIndex] != null && selectedFile != null &&
                selectedFile.SelectedDriver != null && selectedFile.SelectedDriver.Driver_Instance != null &&
                panelIndex >= 0 && selectedPanel != null &&
                !string.IsNullOrWhiteSpace(selectedFile.SelectedDriver.Driver_LoginID) &&
                _panelCurrentList != null && panelIndex < _panelCurrentList.Count &&
                _panelCurrentList[panelIndex] != null && selectedPanel.DataContext != null &&
                selectedPanel.DataContext is ViewModel_EnvVideoPanel &&
                (selectedPanel.DataContext as ViewModel_EnvVideoPanel).CurrentPanel != null)
            {
                NetRecordFileInfoStruct recordFileInfo = selectedFile.NetRecordFileInfo;
                string resultPlayBackByRecordFile = selectedFile.SelectedDriver.Driver_Instance.PlayBackByRecordFile(
                    selectedFile.SelectedDriver.Driver_LoginID, ref recordFileInfo,
                    (selectedPanel.DataContext as ViewModel_EnvVideoPanel).CurrentPanel.Handle,
                    _fDownLoadPosCallBack, IntPtr.Zero); // 网络回放, _fDownLoadDataCallBack, IntPtr.Zero

                if (string.IsNullOrWhiteSpace(resultPlayBackByRecordFile))
                {
#if DEBUG
                    Debug.WriteLine("相同通道在网络回放中，不能同时回放同一通道的多条记录");
#endif
                    return false;
                }
                else // 回放成功
                {
                    IsPlay = _pFilePlayBack[panelIndex].IsPlay = true; // 正在回放
                    _pFilePlayBack[panelIndex].PlayBackHandle = resultPlayBackByRecordFile; // 记录回放句柄
                    _pFilePlayBack[panelIndex].DriverIP = selectedFile.DriverIP;
                    _pFilePlayBack[panelIndex].DriverChannel = selectedFile.DriverChannel;
                    _pFilePlayBack[panelIndex].SelectedFile = selectedFile;
                    (selectedPanel.DataContext as ViewModel_EnvVideoPanel).VideoInformation =
                        string.Format("{0}_通道{1}_{2}", selectedFile.DriverText,
                        selectedFile.DriverChannel, selectedFile.FileStartTime); // 设置视频窗口文本标题信息

                    if (selectedPanel != null && selectedPanel.Tag != null &&
                        selectedPanel.Tag is TagModel)
                    {
                        TagModel panelTag = selectedPanel.Tag as TagModel;
                        panelTag.Driver_Instance = selectedFile.SelectedDriver.Driver_Instance;
                        panelTag.Parameter = null; // Parameter 存放回放速度
                    }

                    return true;
                }
            }
            else
                return false;
        }

        /// <summary>
        /// 停止回放视频
        /// </summary>
        /// <param name="selectedFile">所选文件</param>
        /// <param name="panelIndex">窗口序号</param>
        /// <param name="isClearSelectedFile">停止后是否清空所选文件</param>
        /// <returns>true: 停止成功；false: 停止失败</returns>
        private bool _stopVideo(FileDetailModel selectedFile, int panelIndex, bool isClearSelectedFile)
        {
            if (_pFilePlayBack != null && panelIndex < _pFilePlayBack.Length &&
                _pFilePlayBack[panelIndex] != null && selectedFile != null &&
                selectedFile.SelectedDriver != null && selectedFile.SelectedDriver.Driver_Instance != null &&
                panelIndex >= 0 && !string.IsNullOrWhiteSpace(_pFilePlayBack[panelIndex].PlayBackHandle) &&
                _panelCurrentList != null && panelIndex < _panelCurrentList.Count &&
                _panelCurrentList[panelIndex] != null)
            {
                if (selectedFile.SelectedDriver.Driver_Instance.PlayBackControl(
                    _pFilePlayBack[panelIndex].PlayBackHandle, "Stop")) // 停止正在回放的视频，需要传递回放句柄
                {
                    _clearValue(_panelCurrentList[panelIndex], panelIndex, isClearSelectedFile); // 清除特殊值
                    return true;
                }
                else
                {
                    AutoCloseNoticeWindow.Show("停止回放失败！", false);
                    return false;
                }
            }
            else
                return false;
        }

        /// <summary>
        /// 清除特殊值
        /// </summary>
        /// <param name="isClearSelectedFile"></param>
        private void _clearValue(EnvVideoPanel selectedPanel, int panelIndex, bool isClearSelectedFile)
        {
            if (_pFilePlayBack != null && panelIndex < _pFilePlayBack.Length &&
                _pFilePlayBack[panelIndex] != null &&
                selectedPanel != null && selectedPanel.DataContext != null &&
                selectedPanel.DataContext is ViewModel_EnvVideoPanel &&
                selectedPanel.Tag != null && selectedPanel.Tag is TagModel)
            {
                IsPlay = _pFilePlayBack[panelIndex].IsPlay = false; // 未回放
                _pFilePlayBack[panelIndex].PlayBackHandle = string.Empty;
                _pFilePlayBack[panelIndex].DriverIP = string.Empty;
                _pFilePlayBack[panelIndex].DriverChannel = uint.MinValue;
                if (isClearSelectedFile) // 清空所选文件
                    _pFilePlayBack[panelIndex].SelectedFile = null;
                (selectedPanel.DataContext as ViewModel_EnvVideoPanel).CurrentPanel.Refresh(); // 刷新
                (selectedPanel.DataContext as ViewModel_EnvVideoPanel).VideoInformation = string.Empty; // 不显示标题
                (selectedPanel.Tag as TagModel).Driver_Instance = null;
                (selectedPanel.Tag as TagModel).Parameter = null;
            }
        }

        /// <summary>
        /// 显示回放速度标题
        /// </summary>
        /// <param name="panelTag"></param>
        /// <param name="vm_EnvVideoPanel"></param>
        private void _showPlaySpeedVideoInformation(TagModel panelTag,
            ViewModel_EnvVideoPanel vm_EnvVideoPanel)
        {
            if (panelTag == null || panelTag.Parameter == null ||
                vm_EnvVideoPanel == null || vm_EnvVideoPanel.VideoInformation == null)
                return;

            if ((int)panelTag.Parameter < 0)
            {
                vm_EnvVideoPanel.VideoInformation =
                    string.Format("[X1/{0}]{1}", (int)(1 / Math.Pow(2, (int)panelTag.Parameter)),
                    vm_EnvVideoPanel.VideoInformation.Substring(vm_EnvVideoPanel.VideoInformation.IndexOf(']') + 1))
                    .Replace("[X1]", string.Empty);
            }
            else
            {
                vm_EnvVideoPanel.VideoInformation =
                    string.Format("[X{0}]{1}", Math.Pow(2, (int)panelTag.Parameter),
                    vm_EnvVideoPanel.VideoInformation.Substring(vm_EnvVideoPanel.VideoInformation.IndexOf(']') + 1))
                    .Replace("[X1]", string.Empty);
            }
        }

        /// <summary>
        /// 将焦点循环移动到下一个视频窗口中
        /// </summary>
        private void _focus2NextPanel()
        {
            if (_panelCurrentList != null &&
                EnvPanelOperationExt.SelectedPanel != null &&
                EnvPanelOperationExt.SelectedPanel.Tag != null &&
                EnvPanelOperationExt.SelectedPanel.Tag is TagModel &&
                (EnvPanelOperationExt.SelectedPanel.Tag as TagModel).Panel_Index >= 0 &&
                (EnvPanelOperationExt.SelectedPanel.Tag as TagModel).Panel_Index < _panelCurrentList.Count)
            {
                int nextPanelIndex;

                TagModel selectedPanelTag = EnvPanelOperationExt.SelectedPanel.Tag as TagModel;
                if (selectedPanelTag.Panel_Index + 1 >= _panelCurrentList.Count)
                {
                    nextPanelIndex = 0; // 回到第一个视频窗口
                }
                else
                {
                    nextPanelIndex = selectedPanelTag.Panel_Index + 1; // 下一个视频窗口
                }

                EnvUtilities.ChangeBorderColor4Preview(_panelCurrentList[nextPanelIndex],
                    _panelCurrentList); // 绘制边框
            }
        }

        /// <summary>
        /// 最大化视频窗口
        /// </summary>
        /// <param name="selectedPanel">当前所选视频窗口</param>
        /// <param name="splitScreen">主界面视频窗口容器</param>
        /// <param name="maxScreen">最大化视频窗口</param>
        /// <param name="doubleAction">共同的双击事件</param>
        private void _showMaxScreen(EnvVideoPanel selectedPanel, Panel splitScreen = null,
            EnvVideoPanel maxScreen = null, Action doubleAction = null)
        {
            try
            {
                if (_panelCurrentList != null && _panelCurrentList.Count == SPLITSCREEN_COUNT + 1 &&
                    selectedPanel != null && selectedPanel.Tag != null &&
                    selectedPanel.Tag is TagModel && _pFilePlayBack != null &&
                    _pFilePlayBack[(selectedPanel.Tag as TagModel).Panel_Index] != null &&
                    _pFilePlayBack[(selectedPanel.Tag as TagModel).Panel_Index].SelectedFile != null) // 必须在回放情况下才能最大化（可暂停时）
                {
                    foreach (EnvVideoPanel videoPanel in _panelCurrentList)
                    {
                        videoPanel.Visibility = Visibility.Collapsed;
                    }

                    _panelCurrentList[SPLITSCREEN_COUNT].Visibility = Visibility.Visible;
                    EnvUtilities.ChangeBorderColor4Preview(_panelCurrentList[SPLITSCREEN_COUNT],
                        _panelCurrentList);// 选中最大化视频窗口

                    TagModel panelTag = selectedPanel.Tag as TagModel; // 原视频窗口
                    TagModel maxPanelTag = EnvPanelOperationExt.SelectedPanel.Tag as TagModel; // 最大化视频窗口
                    maxPanelTag.Wall_Index = panelTag.Panel_Index; // 暂存最小化视频窗口序号

                    PlayVideo(_pFilePlayBack[panelTag.Panel_Index].SelectedFile); // 回放视频（最大化视频窗口）
                    _playVideoInProgress(EnvPanelOperationExt.SelectedPanel, SliderValue); // 进度回放
                }
            }
            catch (System.Exception ex)
            {
#if DEBUG
                Debug.WriteLine(ex.Message);
#endif
            }
        }

        /// <summary>
        /// 最小化视频窗口
        /// </summary>
        /// <param name="splitScreen">主界面视频窗口容器</param>
        /// <param name="maxScreen">最大化视频窗口</param>
        /// <param name="doubleAction">共同的双击事件</param>
        private void _hideMaxScreen(Panel splitScreen = null,
            EnvVideoPanel maxScreen = null, Action doubleAction = null)
        {
            try
            {
                if (_panelCurrentList != null && _panelCurrentList.Count == SPLITSCREEN_COUNT + 1 &&
                    EnvPanelOperationExt.SelectedPanel != null && EnvPanelOperationExt.SelectedPanel.Tag != null &&
                    EnvPanelOperationExt.SelectedPanel.Tag is TagModel && _pFilePlayBack != null &&
                    _pFilePlayBack[(EnvPanelOperationExt.SelectedPanel.Tag as TagModel).Panel_Index] != null)
                {
                    foreach (EnvVideoPanel videoPanel in _panelCurrentList)
                    {
                        videoPanel.Visibility = Visibility.Visible;
                    }

                    _panelCurrentList[SPLITSCREEN_COUNT].Visibility = Visibility.Collapsed;
                    TagModel maxPanelTag = EnvPanelOperationExt.SelectedPanel.Tag as TagModel; // 最大化视频窗口

                    EnvUtilities.ChangeBorderColor4Preview(_panelCurrentList[maxPanelTag.Wall_Index],
                        _panelCurrentList); // 还原选中回放视频窗口
                    PlayVideo(_pFilePlayBack[maxPanelTag.Panel_Index].SelectedFile); // 回放视频（最小化视频窗口）
                    _playVideoInProgress(_panelCurrentList[maxPanelTag.Wall_Index], SliderValue); // 进度回放
                }
            }
            catch (System.Exception ex)
            {
#if DEBUG
                Debug.WriteLine(ex.Message);
#endif
            }
        }

        /// <summary>
        /// 停止指定窗口中的视频
        /// </summary>
        /// <param name="currPanel">要停止的 Panel</param>
        private void _stopPanelPlayBack(EnvVideoPanel currPanel)
        {
            try
            {
                PlayerController_StopEvent(currPanel, null);
            }
            catch (System.Exception ex)
            {
#if DEBUG
                Debug.WriteLine(ex.Message);
#endif
            }
        }

        /// <summary>
        /// 按进度回放
        /// </summary>
        /// <param name="selectedPanel">所选 Panel</param>
        /// <param name="currentSliderValue">进度值</param>
        private void _playVideoInProgress(EnvVideoPanel selectedPanel, double currentSliderValue)
        {
            if (_pFilePlayBack != null && selectedPanel != null && selectedPanel.Tag != null &&
                selectedPanel.Tag is TagModel &&
                (selectedPanel.Tag as TagModel).Driver_Instance != null &&
                _pFilePlayBack[(selectedPanel.Tag as TagModel).Panel_Index] != null)
            {
                TagModel panelTag = selectedPanel.Tag as TagModel;
                if (!_pFilePlayBack[panelTag.Panel_Index].IsPlay) // 未回放时
                {
                    PlayerController_PlayEvent(null, null);
                }

                uint offValue = (uint)(currentSliderValue * (_pFilePlayBack[panelTag.Panel_Index].SelectedFile.NetRecordFileInfo.size / SLIDER_MAXVALUE));
                // 按文件回放：按字节偏移回放回放
                if (panelTag.Driver_Instance.PlayBackControl(_pFilePlayBack[panelTag.Panel_Index].PlayBackHandle,
                    "SeekByBit", offValue)) // 共 SLIDER_MAXVALUE 刻度
                {
#if DEBUG
                    Debug.WriteLine("进度条更改成功。");
#endif
                }
                else
                {
#if DEBUG
                    Debug.WriteLine("进度条更改失败。");
#endif
                }
            }
        }

        /// <summary>
        /// 释放资源
        /// </summary>
        private void _dispose()
        {
            if (_pFilePlayBack != null)
            {
                for (int i = 0; i < _pFilePlayBack.Length; i++)
                {
                    if (_panelCurrentList != null &&
                        i < _panelCurrentList.Count &&
                        _panelCurrentList[i] != null &&
                        _pFilePlayBack[i].SelectedFile != null &&
                        _pFilePlayBack[i].SelectedFile.SelectedDriver != null &&
                        _pFilePlayBack[i].SelectedFile.SelectedDriver.Driver_Instance != null &&
                        !string.IsNullOrWhiteSpace(_pFilePlayBack[i].PlayBackHandle))
                    {
                        if (!_stopVideo(_pFilePlayBack[i].SelectedFile, i, true)) // 逐个停止正在回放的视频
                        {
#if DEBUG
                            Debug.WriteLine("停止回放失败！");
#endif
                        }
                        else
                        {
#if DEBUG
                            Debug.WriteLine("停止回放成功！");
#endif
                        }
                    }
                }
            }
        }

        #endregion
    }
}
